def lazy_sum(*args):
    def sum():
        ax =0
        for n in args:
            ax=ax+n
        return ax

    return sum

f=lazy_sum(1,3,5,7,9)
print("返回函数指针：",f)
print('计算调用：',f())

#lazy_sum()时，每次调用都会返回一个新的函数，即使传入相同的参数：
f2=lazy_sum(1,3,5,7,9)
f1=lazy_sum(1,3,5,7,9)
print(f1==f2)

#返回闭包时牢记一点：返回函数不要引用任何循环变量，或者后续会发生变化的变量。
def count():
    fs=[]
    for i in range(1,4):
        def f():
            return i*i
        fs.append(f)
    return fs
f1,f2,f3=count()
print(count())
f1()
print(f1())
f2()
print(f2())
f3()
print(f3())
#原因就在于返回的函数引用了变量i，但它并非立刻执行。等到3个函数都返回时，它们所引用的变量i已经变成了3，因此最终结果为9。

#如果一定要引用循环变量
def count():
    def f(j):
        def g():
            return j*j
        return g
    fs=[]
    for i in range(1,4):
        fs.append(f(i))
    return fs
f1,f2,f3=count()

print(f1())
print(f2())
print(f3())

#使用闭包，就是内层函数引用了外层函数的局部变量。如果只是读外层变量的值，我们会发现返回的闭包函数调用一切正常：


def inc():
    x = 0
    def fn():
        # 仅读取x的值:
        return x + 1
    return fn

f = inc()
print(f()) # 1
print(f()) # 1

#把外层变量的值，在赋值返回就不行，除非加nonlocal
def inc():
    x = 0
    def fn():
        #使用闭包时，对外层变量赋值前，需要先使用nonlocal声明该变量不是当前函数的局部变量。
        nonlocal x
        x = x + 1
        return x
    return fn

f = inc()
print(f()) # 1
print(f()) # 2
